/*
 * @Author: daniel_du dll_2018@126.com
 * @Date: 2022-05-01 06:35:50
 * @LastEditors: daniel_du dll_2018@126.com
 * @LastEditTime: 2022-05-09 15:46:07
 * @FilePath: /safe_transmission_platform/src/server/serverOp.h
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#ifndef __SERVEROP_H__
#define __SERVEROP_H__
#include <memory>
#include <config.h>
#include "tcpServer.h"
#include <string>
#include <sstream>
#include <config.h>
#include "threadpool.h"
#include "tcpSocket.h"
#include "requestMsg.pb.h"
#include "mysqlop.h"
//处理客户端请求

//需要加锁

struct ServeropDefine
{
    ServeropDefine():serverid(""),ip(""),port(6666),host("127.0.0.1"),user("root"),password("daniel"),database(""),dbport(3306)
    {}
    ServeropDefine(const std::string& serveridVal, const std::string& ipVal, uint16_t portVal,const std::string& hostVal, const std::string& userVal, const std::string& pwd, const std::string& databaseVal, uint32_t dbPortVal):serverid(serveridVal),ip(ipVal),port(portVal),host(hostVal),user(userVal),password(pwd),database(databaseVal),dbport(dbPortVal)
    {}

    std::string serverid;
    std::string ip;
    uint16_t port;
    //数据库相关的配置
    std::string host;
    std::string user;
    std::string password;
    std::string database;
    uint32_t dbport;       
};
class ServerOp
{
public:
    using ptr=std::shared_ptr<ServerOp>;
    enum AESKeyLen{LEN16=16,LEN24=24,LEN32=32};
    //启动服务器，监听，收到消息，创建TcpSocekt，交给线程池处理
    ServerOp();
    ~ServerOp();
    void answer(daniel::TcpSocket::ptr tcpSocket);
    //密钥协商
    std::string keyNego(const RequestMsg& msg);
    //密钥验证
    void keyCheck(const RequestMsg& msg);
    //密钥注销
    void keyCancel(const RequestMsg& msg);
private:
    std::string generateRandStr(AESKeyLen len);
    
private:
    ServeropDefine m_serverDefine;
    daniel::TcpServer m_server;
    daniel::ThreadPool::ptr m_threadpool;
    MysqlOp m_mysqldb;
};


/****yml文件内容******
serveropdefine:
  serverid: "89757
  ip: ""
  port: 6789
  host: "127.0.0.1"
  user: "root"
  password: "daniel"
  database: "secretKey"
  dbport: 3306
********************/
template <>
class daniel::LexicalCast<ServeropDefine, std::string>
{
public:
    std::string operator()(const ServeropDefine& serveropDefine)
    {
        YAML::Node root;
        YAML::Node child;
        //服务器相关配置
        child["serverid"]=serveropDefine.serverid;
        child["ip"]=serveropDefine.ip;
        child["port"]=serveropDefine.port;
        //数据库相关配置
        child["host"]=serveropDefine.host;
        child["user"]=serveropDefine.user;
        child["password"]=serveropDefine.password;
        child["database"]=serveropDefine.database;
        child["dbport"]=serveropDefine.dbport;
        root["serveropdefine"]=child;
        std::stringstream ss;
        ss<<root;
        return ss.str();
    }
};

template<>
class daniel::LexicalCast<std::string, ServeropDefine>
{
public:
    ServeropDefine operator()(const std::string& str)
    {
        YAML::Node root=YAML::Load(str);
        ServeropDefine serverDefine;
        serverDefine.serverid=root["serverid"].as<std::string>();
        serverDefine.ip=root["ip"].as<std::string>();
        serverDefine.port=root["port"].as<uint16_t>();

        serverDefine.host=root["host"].as<std::string>();
        serverDefine.user=root["user"].as<std::string>();
        serverDefine.password=root["password"].as<std::string>();
        serverDefine.database=root["database"].as<std::string>();
        serverDefine.dbport=root["dbport"].as<uint32_t>();

        return serverDefine;
    }        
};

#endif